import 'package:json_annotation/json_annotation.dart';

import '../exception/api_exception.dart';

part 'net_result.g.dart';

mixin INetResult<T> {
  String getMessage();

  int getCode();

  T? getResult();

  void checkResultCode();

  void checkResultData();

  /// 校验code，并将数据提取出来
  T result_data() {
    checkResultCode();
    checkResultData();
    return getResult()!;
  }

  /// 校验 code
  INetResult<T> result_result() {
    checkResultCode();
    return this;
  }
}


@JsonSerializable(genericArgumentFactories: true)
class NetResult<T> with INetResult<T> {
  // /**
  //  * 数据返回成功
  //  */
  static int CODE_SUCCESS = 200;
  static int CODE_NO_CODE = -1;

  NetResult();

  String? msg;
  int? code;
  T? data;

  @override
  void checkResultCode() {
    int code = getCode();
    if (code != NetResult.CODE_SUCCESS && code != null) {
      throw ApiException(code: getCode(), message: getMessage());
    }
  }

  @override
  void checkResultData() {
    if (getResult() == null) throw ApiEmptyException(getCode());
  }

  @override
  int getCode() {
    if (code == null) return CODE_NO_CODE;
    return code ?? CODE_NO_CODE;
  }

  @override
  String getMessage() {
    return msg ?? "";
  }

  @override
  T? getResult() {
    return data;
  }

  factory NetResult.fromJson(Map<String, dynamic> json, T Function(dynamic json) fromJsonT) =>
      _$NetResultFromJson(json, fromJsonT);

  ///注意这里的写法
  Map<String, dynamic> toJson(Object? Function(T value) toJsonT) =>
      _$NetResultToJson(this, toJsonT);
}
